﻿#include "ucolorpickerdialog.h"
#include "widgets/ulineedit.h"
#include "widgets/ucolorpicker.h"
#include "widgets/ulabel.h"
#include "widgets/upushbutton.h"
#include "widgets/ucommonbutton.h"
#include "uapplication.h"

#include <QFormLayout>
#include <QVBoxLayout>

class UColorPickerDialogPrivate
{
public:
    UColorPickerDialogPrivate(UColorPickerDialog* q) : q_ptr(q) {}
    ~UColorPickerDialogPrivate() {};

    void init();

    void initConnection();

    void onColorChanged(const QColor &color);

    void onRTextEdited(const QString &text);

    void onGTextEdited(const QString &text);

    void onBTextEdited(const QString &text);

    void onHexTextEdited(const QString &text);

private:
    Q_DECLARE_PUBLIC(UColorPickerDialog)
    Q_DISABLE_COPY(UColorPickerDialogPrivate)
    UColorPickerDialog* const q_ptr = nullptr;
    UColorPicker *m_pColorPicker = nullptr;
    ULineEdit *m_pRLineEdit = nullptr;
    ULineEdit *m_pGLineEdit = nullptr;
    ULineEdit *m_pBLineEdit = nullptr;
    ULineEdit *m_pHexLineEdit = nullptr;
    ULabel *m_pRLabel = nullptr;
    ULabel *m_pGLabel = nullptr;
    ULabel *m_pBLabel = nullptr;
    ULabel *m_pHexLabel = nullptr;
    UPushButton *m_pCancleButton = nullptr;
    UCommonButton *m_pOkButton = nullptr;
    UWidget *m_pColorLabel = nullptr;
};

void UColorPickerDialogPrivate::init()
{
    Q_Q(UColorPickerDialog);

    m_pColorPicker = new UColorPicker(q);
    m_pColorPicker->setMinimumSize(260, 260);
    m_pColorPicker->setShowColorText(false);
    m_pRLineEdit = new ULineEdit(q);
    m_pGLineEdit = new ULineEdit(q);
    m_pBLineEdit = new ULineEdit(q);
    m_pHexLineEdit = new ULineEdit(q);
    m_pRLabel = new ULabel(QObject::tr("R:"), q);
    m_pGLabel = new ULabel(QObject::tr("G:"), q);
    m_pBLabel = new ULabel(QObject::tr("B:"), q);
    m_pHexLabel = new ULabel(QObject::tr("Hex:"), q);
    m_pCancleButton = new UPushButton(QObject::tr("Cancle"), q);
    m_pCancleButton->setRadius(8);
    m_pOkButton = new UCommonButton(QObject::tr("Confirm"), q);
    m_pOkButton->setBackgroundRole(QPalette::Highlight);
    m_pOkButton->setRadius(8);
    m_pOkButton->setRadiuPosition(RadiuPosition::All);

    QVBoxLayout *pVLayout = new QVBoxLayout();
    pVLayout->setSpacing(16);
    m_pColorLabel = new UWidget(q);
    pVLayout->addWidget(m_pColorLabel);

    QFormLayout *pFormLayout = new QFormLayout;
    pFormLayout->setSpacing(10);
    pFormLayout->addRow(m_pRLabel, m_pRLineEdit);
    pFormLayout->addRow(m_pGLabel, m_pGLineEdit);
    pFormLayout->addRow(m_pBLabel, m_pBLineEdit);
    pFormLayout->addRow(m_pHexLabel, m_pHexLineEdit);
    pVLayout->addLayout(pFormLayout);

    QHBoxLayout *pHLayout = new QHBoxLayout;
    pHLayout->addWidget(m_pColorPicker);
    pHLayout->addLayout(pVLayout);

    QHBoxLayout *pButtonLayout = new QHBoxLayout;
    pButtonLayout->addSpacing(20);
    pButtonLayout->addWidget(m_pCancleButton);
    pButtonLayout->addWidget(m_pOkButton);
    pButtonLayout->addSpacing(20);

    QWidget *pWidget = new QWidget(q);
    QVBoxLayout *mainLayout = new QVBoxLayout(pWidget);
    mainLayout->addLayout(pHLayout);
    mainLayout->addSpacing(10);
    mainLayout->addLayout(pButtonLayout);

    q->setContentWidget(pWidget);
}

void UColorPickerDialogPrivate::initConnection()
{
    Q_Q(UColorPickerDialog);
    QObject::connect(m_pColorPicker, &UColorPicker::colorChanged, q, [=](const QColor &color) {
        onColorChanged(color);
    });
    QObject::connect(m_pCancleButton, &QPushButton::clicked, q, &UColorPickerDialog::reject);
    QObject::connect(m_pOkButton, &QPushButton::clicked, q, &UColorPickerDialog::accept);

    QObject::connect(m_pRLineEdit, &ULineEdit::textEdited, q, [=](const QString &text) {
        onRTextEdited(text);
    });
    QObject::connect(m_pGLineEdit, &ULineEdit::textEdited, q, [=](const QString &text) {
        onGTextEdited(text);
    });
    QObject::connect(m_pBLineEdit, &ULineEdit::textEdited, q, [=](const QString &text) {
        onBTextEdited(text);
    });
    QObject::connect(m_pHexLineEdit, &ULineEdit::textEdited, q, [=](const QString &text) {
        onHexTextEdited(text);
    });
}

void UColorPickerDialogPrivate::onColorChanged(const QColor &color)
{
    m_pColorLabel->setBackgroundColor(color);
    m_pRLineEdit->setText(QString::number(color.red()));
    m_pGLineEdit->setText(QString::number(color.green()));
    m_pBLineEdit->setText(QString::number(color.blue()));
    m_pHexLineEdit->setText(color.name());
}

void UColorPickerDialogPrivate::onRTextEdited(const QString &text)
{
    Q_Q(UColorPickerDialog);
    bool bOk = false;
    int number = m_pRLineEdit->text().toInt(&bOk);
    if (bOk && (number >=0 && number <= 255)) {
        QColor color = m_pColorPicker->color();
        q->setColor(QColor(number, color.green(), color.blue()));
    }
}

void UColorPickerDialogPrivate::onGTextEdited(const QString &text)
{
    Q_Q(UColorPickerDialog);
    bool bOk = false;
    int number = m_pGLineEdit->text().toInt(&bOk);
    if (bOk && (number >=0 && number <= 255)) {
        QColor color = m_pColorPicker->color();
        q->setColor(QColor(color.red(), number, color.blue()));
    }
}

void UColorPickerDialogPrivate::onBTextEdited(const QString &text)
{
    Q_Q(UColorPickerDialog);
    bool bOk = false;
    int number = m_pBLineEdit->text().toInt(&bOk);
    if (bOk && (number >=0 && number <= 255)) {
        QColor color = m_pColorPicker->color();
        q->setColor(QColor(color.red(), color.green(), number));
    }
}

void UColorPickerDialogPrivate::onHexTextEdited(const QString &text)
{
    Q_Q(UColorPickerDialog);
    QColor currentColor(text);
    if (currentColor.isValid())
        q->setColor(currentColor);
}

UColorPickerDialog::UColorPickerDialog(QWidget* parent) : UDialog(parent)
    , d_ptr(new UColorPickerDialogPrivate(this))
{
    d_ptr->init();
    d_ptr->initConnection();
    setTitleIcon(uApp->windowIcon());
    setMessageBoxTitle(tr("Choice Color"));
}

UColorPickerDialog::~UColorPickerDialog()
{
}

void UColorPickerDialog::setColor(const QColor &color)
{
    Q_D(UColorPickerDialog);
    d->m_pColorPicker->setColor(color);
}

QColor UColorPickerDialog::color() const
{
    Q_D(const UColorPickerDialog);
    return d->m_pColorPicker->color();
}


